package com.smartStatus.security.comment;

import com.smartStatus.core.constant.SecurityConstant;
import com.smartStatus.security.exception.ResourceAuthExceptionEntryPoint;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.web.client.RestTemplate;

/**
 * @ClassName : StatusResourceServerConfigAdapter
 * @Author : lby
 * @Date: 2021/5/6 21:11
 * @Description : Ribbon 负载均衡security配置
 */
@Slf4j
public class StatusResourceServerConfigAdapter extends ResourceServerConfigurerAdapter {
    @Autowired
    protected ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint;
    //    @Autowired
//    protected RemoteTokenServices remoteTokenServices;
    @Autowired
    private PermitAllUrlProperties permitAllUrlProperties;
    @Autowired
    private RestTemplate lbRestTemplate;
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;


    /**
     * 默认的配置，对外暴露
     *
     * @param httpSecurity
     */
    @Override
    @SneakyThrows
    public void configure(HttpSecurity httpSecurity) {
        //允许使用iframe 嵌套，避免swagger-ui 不被加载的问题
        httpSecurity.headers().frameOptions().disable();
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>
                .ExpressionInterceptUrlRegistry registry = httpSecurity
                .authorizeRequests();
        permitAllUrlProperties.getIgnoreUrls()
                .forEach(url -> registry.antMatchers(url).permitAll());
        registry.anyRequest().authenticated()
                .and().csrf().disable();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
//        DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
//        UserAuthenticationConverter userTokenConverter = new StatusUserAuthenticationConverter();
//        accessTokenConverter.setUserTokenConverter(userTokenConverter);
//        RemoteTokenServices tokenServices = new RemoteTokenServices();
//        tokenServices.setClientId("ENC(ltJPpR50wT0oIY9kfOe1Iw==)");
//        tokenServices.setClientSecret("ENC(ltJPpR50wT0oIY9kfOe1Iw==)");
//        tokenServices.setCheckTokenEndpointUrl("http://smart-status-auth/oauth/check_token");
//        tokenServices.setRestTemplate(lbRestTemplate);
//        tokenServices.setAccessTokenConverter(accessTokenConverter);
//        resources.authenticationEntryPoint(resourceAuthExceptionEntryPoint)
//                .tokenServices(tokenServices);
        resources.stateless(false);
        resources.tokenStore(createNewTokenStore());
    }

    @Bean
    public TokenStore createNewTokenStore() {
        RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
        // 设定Token 的前缀
        tokenStore.setPrefix(SecurityConstant.smartStatus_PREFIX + SecurityConstant.OAUTH_PREFIX);
        tokenStore.setAuthenticationKeyGenerator(new DefaultAuthenticationKeyGenerator() {
            @Override
            public String extractKey(OAuth2Authentication authentication) {
                return super.extractKey(authentication);
            }
        });
        return tokenStore;
    }
}
